package com.bolt.report.business.modules.link.dto.converter;

import com.bolt.common.utils.JacksonUtil;
import com.bolt.common.utils.StrUtil;
import com.bolt.report.business.modules.link.dto.ReportLinkDTO;
import com.bolt.report.business.modules.link.entity.ReportLinkEntity;
import com.bolt.report.definition.HyperlinkDefinition;
import com.bolt.report.engine.model.Expression;
import com.bolt.report.exception.ReportException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.commons.collections.map.LinkedMap;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Created by Administrator on 2018/11/27.
 */
public class ReportLinkConverter {
    private ReportLinkConverter() {
// do nothing
    }

    /**
     * Entity对象转换为DTO对象
     *
     * @param reportLink DO对象
     * @return DTO对象
     */
    public static ReportLinkDTO toDTO(ReportLinkEntity reportLink) {
        if (Objects.isNull(reportLink)) {
            return null;
        }
        ReportLinkDTO result = new ReportLinkDTO();
        result.setId(reportLink.getId());
        result.setReportId(reportLink.getReportId());
        result.setParameter(reportLink.getParameter());
        result.setEjectType(reportLink.getEjectType());
        result.setLinkName(reportLink.getLinkName());
        result.setHttpMethod(reportLink.getHttpMethod());
        result.setLinkType(reportLink.getLinkType());
        result.setHttpUrl(reportLink.getHttpUrl());
        result.setLinkChartId(reportLink.getLinkChartId());
        result.setScript(reportLink.getScript());
        result.setRequirement(reportLink.getRequirement());
        // TODO
        return result;
    }

    public static HyperlinkDefinition toDefinition(ReportLinkEntity reportLink) {
        if (Objects.isNull(reportLink)) {
            return null;
        }
        HyperlinkDefinition definition = new HyperlinkDefinition();
        definition.setReportId(reportLink.getReportId());
        if (StrUtil.isNotBlank(reportLink.getParameter())) {
            String json = reportLink.getParameter();
            try {
                JsonNode jsonObject = JacksonUtil.getObjectMapper().readTree(json);
                Map<String, String> param = new LinkedMap();
                if (jsonObject.isArray()) {
                    for (JsonNode node : (ArrayNode) jsonObject) {
                        String dbCode = node.get("dbCode").asText();
                        String paramValue = node.get("paramValue").asText();
                        if (Expression.isDynamicExpr(paramValue)) {
                            param.put(node.get("paramName").asText(), paramValue);
                        } else {
                            String expr = StrUtil.isNotEmpty(dbCode) ? StrUtil.format("${{}.{}}", dbCode, paramValue) : paramValue;
                            param.put(node.get("paramName").asText(), expr);
                        }
                    }
                    definition.setParameter(param);
                }
            } catch (Exception ex) {
                throw new ReportException(ex);
            }
        }
        definition.setEjectType(reportLink.getEjectType());
        definition.setLinkName(reportLink.getLinkName());
        definition.setHttpMethod(reportLink.getHttpMethod());
        definition.setLinkType(reportLink.getLinkType());
        definition.setHttpUrl(reportLink.getHttpUrl());
        definition.setLinkChartId(reportLink.getLinkChartId());
        definition.setScript(reportLink.getScript());
        // TODO
        return definition;
    }

    /**
     * DTO对象转换为Entity对象
     *
     * @param reportLink DO对象
     * @return VO对象
     */
    public static ReportLinkEntity toEntity(ReportLinkDTO reportLink) {
        if (Objects.isNull(reportLink)) {
            return null;
        }
        ReportLinkEntity result = new ReportLinkEntity();
        if (StrUtil.isNotBlank(reportLink.getId())) {
            result.setId(reportLink.getId());
        } else {
            result.setId(null);
        }
        result.setReportId(reportLink.getReportId());
        result.setParameter(reportLink.getParameter());
        result.setEjectType(reportLink.getEjectType());
        result.setLinkName(reportLink.getLinkName());
        result.setHttpMethod(reportLink.getHttpMethod());
        result.setLinkType(reportLink.getLinkType());
        result.setHttpUrl(reportLink.getHttpUrl());
        result.setLinkChartId(reportLink.getLinkChartId());
        result.setScript(reportLink.getScript());
        result.setRequirement(reportLink.getRequirement());
        // TODO
        return result;
    }

    /**
     * DTO对象转换为DO对象
     *
     * @param reportLink DO对象
     * @return VO对象
     */
    public static ReportLinkEntity toEntity(ReportLinkEntity result, ReportLinkDTO reportLink) {
        if (Objects.isNull(reportLink)) {
            return null;
        }
        result.setReportId(reportLink.getReportId());
        result.setParameter(reportLink.getParameter());
        result.setEjectType(reportLink.getEjectType());
        result.setLinkName(reportLink.getLinkName());
        result.setHttpMethod(reportLink.getHttpMethod());
        result.setLinkType(reportLink.getLinkType());
        result.setHttpUrl(reportLink.getHttpUrl());
        result.setLinkChartId(reportLink.getLinkChartId());
        result.setScript(reportLink.getScript());
        result.setRequirement(reportLink.getRequirement());
// TODO
        return result;
    }

    /**
     * 批量 Entity对象转换为DTO对象
     *
     * @param reportLinkList Entity集合对象
     * @return DTO对象
     */
    public static List<ReportLinkDTO> toDTO(List<ReportLinkEntity> reportLinkList) {
        if (Objects.isNull(reportLinkList)) {
            return null;
        }
        return reportLinkList.stream().map(ReportLinkConverter::toDTO).collect(Collectors.toList());
    }

    /**
     * 批量 DTO对象转换为Entity对象
     *
     * @param reportLinkList Entity集合对象
     * @return DTO对象
     */
    public static List<ReportLinkEntity> toEntity(List<ReportLinkDTO> reportLinkList) {
        if (Objects.isNull(reportLinkList)) {
            return null;
        }
        return reportLinkList.stream().map(ReportLinkConverter::toEntity).collect(Collectors.toList());
    }

    public static List<HyperlinkDefinition> toDefinition(List<ReportLinkEntity> reportLinkList) {
        if (Objects.isNull(reportLinkList)) {
            return null;
        }
        return reportLinkList.stream().map(ReportLinkConverter::toDefinition).collect(Collectors.toList());
    }

}
